/*=====================================================================================================================
                    Copyright(c) 2005 Geometric PLM Software Corp. All rights reserved.
                             Unpublished - All rights reserved
=======================================================================================================================
File description:
    Filename: tc_epm.c
    Module  : (geometric) itk module.

        This file manages the operations of EPM(Enterprise Process Modeling).

=======================================================================================================================
Date               Name              Description of Change
28-Jul-2009        Penn,Xie          Initialize creation
$HISTORY$
=====================================================================================================================*/
#include <ai\sample_err.h>
#include <epm\epm.h>
#include <tccore\aom_prop.h>
#include <tccore\aom.h>
#include <time.h>


#ifdef BUILD_IMAN 

#include <imantype.h>

#define  GTC_strcmp             iman_strcmp
#define  GTCTYPE_name_size_c            IMANTYPE_name_size_c
#define  GTCTYPE_ask_object_type        IMANTYPE_ask_object_type
#define  GTCTYPE_ask_name               IMANTYPE_ask_name
#else // Teamcenter

#include <tccore\tctype.h>

#define  GTC_strcmp             tc_strcmp
#define  GTCTYPE_name_size_c            TCTYPE_name_size_c
#define  GTCTYPE_ask_object_type        TCTYPE_ask_object_type
#define  GTCTYPE_ask_name               TCTYPE_ask_name

#endif

#include "tc_utils.h"
#include "tc_type.h"
#include "tc_epm.h"

int GEPM_get_action_objects( tag_t task, const char *typeName, int *objCnt, tag_t **objects )
{
    return GEPM_ask_action_objects(task, GAFT_EX_WSO, typeName, objCnt, objects);
}

int GEPM_ask_action_objects( tag_t task, enum GEPM_Action_find_type_e enumType, const char *typeName, int *objCnt, tag_t **objects )
{
    int     ifail        = ITK_ok;

    int     cnt          = 0;
    int     matchedCnt   = 0;
    tag_t   job          = NULLTAG;
    tag_t   rootTask     = NULLTAG;
    tag_t   *attachments = NULL;
    tag_t   typeTag      = NULLTAG;
    int     i            = 0;
    int     inc          = 0;
    logical isType       = false;
    logical *isMatched   = NULL;

    char objTypeName[GTCTYPE_name_size_c + 1] = {0};
    char wsoTypeName[WSO_name_size_c + 1] = {0};

    *objCnt  = 0;
    *objects = NULL;

    ifail = EPM_ask_job( task, &job );
    CALL( ifail );
    ifail = EPM_ask_root_task( job, &rootTask );
    CALL( ifail );
    ifail = EPM_ask_attachments( rootTask, EPM_target_attachment, &cnt, &attachments );
    CALL( ifail );
    if (cnt == 0)
    {
        return ifail;
    }

    // Get the matched type.
    isMatched = (logical*)MEM_alloc( cnt * sizeof(logical) );
    for (i = 0; (i < cnt && ifail == ITK_ok); i++)
    {
        isType = false;
        if ( enumType == GAFT_EX_TCTYPE)//Like BOMView (Revision)
        {
            if ((ifail = GTCTYPE_ask_object_type( attachments[i], &typeTag )) == ITK_ok
                && (ifail = GTCTYPE_ask_name(typeTag, objTypeName)) == ITK_ok
                && GTC_strcmp(typeName, objTypeName) == 0)
            {
                isType = true;
            }
        }
        else if (enumType == GAFT_EX_WSO)
        {
            if( (ifail = WSOM_ask_object_type( attachments[i], wsoTypeName )) == ITK_ok
                && GTC_strcmp(typeName, wsoTypeName) == 0 )
            {
                isType = true;
            }
        }
        if (ifail == ITK_ok)
        {
            isMatched[i] = isType;
            if ( isType )
                matchedCnt++;
        }
    }

    if (ifail == ITK_ok)
    {
        if (matchedCnt > 0)
        {
            *objects = (tag_t*)MEM_alloc( matchedCnt * sizeof( tag_t ) );
            for (i = 0; i < cnt; i++)
            {
                if ( isMatched[i] == true)
                {
                    (*objects)[inc] = attachments[i];
                    inc++;
                }
            }
            *objCnt = inc;
        }
    }

    MEM_free( isMatched );
    MEM_free( attachments );

    return ifail;
}

logical GEPM_is_exist_object( tag_t rootTask, tag_t object )
{
    int ifail = ITK_ok;
    int cnt = 0;
    tag_t   *attachments = NULL;
    int i = 0;
    logical isExist = false;

    DO( ifail = EPM_ask_attachments( rootTask, EPM_target_attachment, &cnt, &attachments ) );
    if (cnt == 0)
    {
        return false;
    }

    // Get the matched type.
    for (i = 0; i < cnt; i++)
    {
        if (attachments[i] == object)
        {
            isExist = true;
            break;
        }
    }
    MEM_free( attachments );
    return isExist;    
}

int GEPM_find( const char *statusName, logical *found, tag_t *taskType )
{
    static tag_t  enqId = NULLTAG;
    static char   *nameVal;
    int     ifail = ITK_ok;
    int     nInstances = 0;
    tag_t * instances = NULL;;

    *taskType = NULLTAG;

    if ( enqId == NULLTAG )
    {
        tag_t  ttCid = NULLTAG;
        tag_t  ttNameAttrid = NULLTAG;
        if ( (ifail = POM_class_id_of_class( "TaskType", &ttCid )) != POM_ok )
        {
            
            EMH_store_error( EMH_severity_error, ifail );
            return ifail; 
        }
        if ( (ifail = POM_attr_id_of_attr( "tasktype_name", "TaskType", &ttNameAttrid )) != POM_ok )
        {
            EMH_store_error( EMH_severity_error, ifail );
            return ifail; 
        }

        //  undo proof
        POM_cache_for_session( &enqId );

        if ( (ifail = POM_create_enquiry_on_string( ttCid, ttNameAttrid, POM_is_equal_to, &nameVal, &enqId )) != POM_ok )
        {
            EMH_store_error( EMH_severity_error, ifail );
            return ifail; 
        }
    }

    //  Execute enquiry and return the task type found ("There can be only one", etc.)
    nameVal = (char *)statusName;
    if ( (ifail = POM_execute_enquiry( enqId, &nInstances, &instances )) != POM_ok )
    {
        EMH_store_error( EMH_severity_error, ifail );
        return ifail; 
    }

    if ( nInstances > 0 )
    {
        //  Found
        *taskType = instances[0];
        *found = true;
    }
    else
    {
        //  Not found
        *taskType = NULLTAG;
        *found = false;
    }

    MEM_free( instances );
    return ITK_ok;
}

int GEPM_update_release_date( tag_t releaseStatus )
{
    int ifail = ITK_ok;
    // Set the dateReleased to the current date
    time_t createTime;
    date_t date;
    time( &createTime );
    GUTIL_time_to_date( createTime, &date );

    ifail = AOM_set_value_date( releaseStatus, "date_released", date );
    if (ifail  != ITK_ok)
        return ifail;

    ifail = AOM_save(releaseStatus);
    return ifail;
}
